package org.dromara.solonplugins.zbus.broker;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.noear.solon.Utils;
import org.noear.solon.core.AopContext;
import org.noear.solon.core.BeanWrap;
import org.noear.solon.core.Props;
import org.noear.solon.core.util.ResourceUtil;

import io.zbus.kit.StrKit;
import io.zbus.kit.logging.Logger;
import io.zbus.kit.logging.LoggerFactory;
import io.zbus.mq.Broker;
import io.zbus.mq.BrokerConfig;
import io.zbus.transport.ServerAddress;

public class ZbusBrokerBean {
	private final static Logger log = LoggerFactory.getLogger(ZbusBrokerBean.class);

	public static void reg(AopContext context) throws IOException {
		BrokerConfig brokerConfig = createBrokerConfig(context);
		createBroker(context,brokerConfig);
	}
	
	private static BrokerConfig createBrokerConfig(AopContext context) throws IOException {
		Props props = context.cfg();
		BrokerConfig brokerConfig = new BrokerConfig();
		// zbus.broker.readyTimeout
		String readyTimeout = props.get("zbus.broker.readyTimeout");
		if (Utils.isNotBlank(readyTimeout)) {
			brokerConfig.setReadyTimeout(Integer.parseInt(readyTimeout));
			log.debug("zbus.broker.readyTimeout=" + brokerConfig.getReadyTimeout());
		}
		// zbus.broker.clientPoolSize
		String clientPoolSize = props.get("zbus.broker.clientPoolSize");
		if (Utils.isNotBlank(clientPoolSize)) {
			brokerConfig.setClientPoolSize(Integer.parseInt(clientPoolSize));
			log.debug("zbus.broker.clientPoolSize=" + brokerConfig.getClientPoolSize());
		}
		// zbus.trackerList
		String trackerListStr = props.get("zbus.broker.trackerList");
		
		Map<String, String> trackerList = getStringToMap(trackerListStr);
		if (trackerList==null || trackerList.isEmpty()) {
			log.debug("add zbus default tracker 127.0.0.1:15555");
			trackerList.put("zbus.broker.trackerList.default.address", "127.0.0.1:15555");
		}
		for (Map.Entry<String, String> en : trackerList.entrySet()) {
			String key = en.getKey();
			if (!key.endsWith(".address")) {
				continue;
			}
			String name = key.substring(0, key.length() - ".address".length());
			String address = en.getValue().toString();
			boolean sslEnabled = "true".equals(String.valueOf(trackerList.get(name + ".sslEnabled")));
			String certFile = String.valueOf(trackerList.get(name + ".certFile"));
			if (StrKit.isEmpty(address))
				continue;

			log.debug("add tracker: name=%s address=%s sslEnabled=%s", name, address, sslEnabled);

			ServerAddress serverAddress = new ServerAddress(address, sslEnabled);
			if (serverAddress.isSslEnabled()) {
				String certificate = ResourceUtil.getResourceAsString(certFile);
				serverAddress.setCertificate(certificate);
			}
			brokerConfig.addTracker(serverAddress);
		}
		BeanWrap bw = context.wrap("zbusBrokerConfig", brokerConfig);
		context.putWrap(BrokerConfig.class, bw);
		
		return brokerConfig;
	}
	
	private static Broker createBroker(AopContext context,BrokerConfig brokerConfig) {
		Broker broker = new Broker(brokerConfig);
		
		BeanWrap bw = context.wrap("zbusBroker", broker);
		context.putWrap(Broker.class, bw);
		return broker;
	}
	
    private static Map<String, String> getStringToMap(String str) {
        // 判断str是否有值
        if (null == str || "".equals(str)) {
            return null;
        }
        // 根据&截取
        String[] strings = str.split("',");
        // 设置HashMap长度
        int mapLength = strings.length;
        Map<String, String> map = new HashMap<>(mapLength);
        // 循环加入map集合
        for (String string : strings) {
            // 截取一组字符串
            String[] strArray = string.split(":");
            // strArray[0]为KEY strArray[1]为值
            map.put(strArray[0], strArray[1]);
        }
        return map;
    }

}
